package com.lanou.quanttrade.utils.interceptor;

import com.alibaba.fastjson.JSON;
import com.lanou.quanttrade.utils.annotation.RequireLogin;
import com.lanou.quanttrade.utils.javabean.RestObject;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;

@Component
public class LoginInterceptor implements HandlerInterceptor {
    /**
     * 在请求指定的 控制器业务方法之前，进行拦截，判断是否有登录权限。
     * 有权限，放行
     * 没有权限，拦截
     * @param request
     * @param response
     * @param handler
     * @return    true 放行   false 拦截
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if(handler instanceof HandlerMethod){
            //1、判断当前执行的业务方法 是否被注解修饰了
            //1.1、对Handler进行强转
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            //1.2、判断当前方法是否被注解修饰
            RequireLogin requireLogin = handlerMethod.getMethodAnnotation(RequireLogin.class);
            //2、判断当前方法是否需要进行权限校验
            if(requireLogin!=null && requireLogin.value()){
                //3、如果需要进行校验，判断是否有权限，有权限就放行，没有权限就拦截
                //3.1、获取session中的member对象
                Object member = request.getSession().getAttribute("member");
                //3.2、判断member对象是否存在
                if(member==null){
                    //3.3、如果Member不存在，说明没有登录权限，拦截，返回错误信息
                    //处理中文
                    response.setContentType("application/json;charset=utf-8");
                    //向前写出信息
                    PrintWriter writer = response.getWriter();
                    writer.write(JSON.toJSONString(RestObject.ERROR("请先登录！")));
                    //拦截
                    return false;
                }
                //3.4、如果member存在，说明有登录权限直接放行
            }
            //4、如果不需要权限校验，直接放行即可
        }
        //如果不是要拦截的业务方法系列，直接放行
        return true;
    }
}
